import { customRef } from 'vue'

/**
 * 防抖输入
 * @param { object } props 组件的 props
 * @param { object } events 事件集合，run：立即提交；clear：清空计时，用于汉字输入
 * @param { object } emit 组件的 emit
 * @param { number } delay 延迟时间，默认500毫秒
 * @param { string } name v-model的名称，默认 modelValue，用于emit
 */
  const debounceRef = (props, events = {}, emit = () => {}, delay = 500, name = 'modelValue') => {
  // 计时器
  let timeout = null
  // 是否输入状态。输入时取 value；输入完毕取 modelValue 属性
  let isInput = false
  // 内部变量，记录上级的值
  let _value = (typeof props.model === 'object') ? 
    props.model[props.colName] :
    props[name]
  
  // 提交
  const _setValue = (__val) => {
    if (typeof props.model === 'object') {
      props.model[props.colName] = __val
    } else {
      emit(`update:${name}`, __val)
    }
  }

  /**
   * 立即提交的事件
   */
  events.run = () => {
    isInput = false
    clearTimeout(timeout) // 清掉上一次的计时
    _setValue(_value)
  }

  /**
   * 清掉上次计时
   */
  events.clear = () => {
    clearTimeout(timeout) // 清掉上一次的计时
  }

  
  return customRef((track, trigger) => {
    return {
      get () {
        track()
        if (isInput) {
          return _value
        } else {
            if (typeof props.model === 'object') {
            _value = props.model[props.colName]
          } else {
            _value = props[name]
          }
          return _value
        }
      },
      set (val) {
        isInput = true
        _value = val // 绑定值
        trigger() // 输入内容绑定到控件，但是不提交
        clearTimeout(timeout) // 清掉上一次的计时
        timeout = setTimeout(() => {
          _setValue(val)
          isInput = false
        }, delay)
      }
    }
  })
}

export default debounceRef
